package com.ruike.alisurface;

import android.annotation.SuppressLint;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;

import androidx.multidex.MultiDex;

import com.android.print.sdk.util.Utils;
import com.lgh.uvccamera.utils.ThreadUtils;
import com.ruike.alisurface.serialport.QrCodeUtils;
import com.ruike.alisurface.serialport.Ttys1Utils;
import com.ruike.alisurface.serialport.Ttys3Utils;
import com.ruike.alisurface.ui.SystemStart_Aty;
import com.tencent.bugly.crashreport.CrashReport;
import com.voodoo.lib_crashexception.CrashException;
import com.voodoo.lib_crashexception.model.CrashModel;
import com.voodoo.lib_frame.FrameApplication;
import com.voodoo.lib_http.ApiTools;
import com.voodoo.lib_logcat.L;
import com.voodoo.lib_mqtt.MqttOperation;
import com.voodoo.lib_utils.DeviceUtils;
import com.voodoo.lib_utils.SharedUtils;
import com.voodoo.lib_utils.imageLoader.GlideImageLoader;
import com.voodoo.serialport.callback.SerialPortTtys1CallBack;
import com.voodoo.serialport.callback.SerialPortTtys3CallBack;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Properties;

/**
 * Author：voodoo
 * CreateTime：2021/06/07 007 下午 12:35
 * Description：
 */
public class AppApplication extends FrameApplication {
    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        ApiTools.init(this);
        SharedUtils.init(AppApplication.getAppContext());
        initLogCat();
        initCrashException();
        GlideImageLoader.init(this);
        openSerialPort1();
        openSerialPort3();
        MqttOperation.getInstance().setMqttTopicMessageListener(MqttMessageUtils.getInstance());
        ThreadUtils.post(new Runnable() {
            @Override
            public void run() {
                setBuglyConfig();
                initPrinterSDK();
            }
        });
    }

    private void initPrinterSDK() {
        try {
            Properties pro = Utils.getBtConnInfo(this);
            if (pro.isEmpty()) {
                pro.put("mac", "");
            }
        } catch (Exception e) {
            Utils.saveBtConnInfo(this, "");
        }
    }

    /**
     * 初始化Log日志
     */
    private void initLogCat() {
        L.init(this)
                .setLogSwitch(Constant.LogCat.IS_SHOW_LOG) // 设置log总开关，包括输出到控制台和文件，默认开
                .setConsoleSwitch(Constant.LogCat.IS_SHOW_CONSOLE_LOG) // 设置是否输出到控制台开关，默认开
                .setLog2FileSwitch(Constant.LogCat.IS_SAVE_LOG_FILE) // 打印log时是否存到文件的开关，默认关
                .setGlobalTag(Constant.LogCat.LOG_TAG) // 设置log全局标签，默认为空
                .setLogHeadSwitch(Constant.LogCat.LOG_HEAD_SWITCH) // 设置log头信息开关，默认为开
                .setDir(Constant.LogCat.SAVE_FILE_PATH) // 当自定义路径为空时，写入应用的/cache/log/目录中
                .setFilePrefix(Constant.LogCat.FILE_PREFIX) // 当文件前缀为空时，默认为""，即写入文件为"yyyy-MM-dd.log"
                .setBorderSwitch(Constant.LogCat.BORDER_SWITCH) // 输出日志是否带边框开关，默认开
                .setSingleTagSwitch(Constant.LogCat.SIGLE_TAG_SWITCH) // 一条日志仅输出一条，默认开，为美化 AS 3.1.0 的 Logcat
                .setConsoleFilter(Constant.LogCat.CONSOLE_FILTER) // log的控制台过滤器，和logcat过滤器同理，默认Verbose
                .setFileFilter(Constant.LogCat.FILE_FILTER) // log文件过滤器，和logcat过滤器同理，默认Verbose
                .setStackDeep(Constant.LogCat.STACK_DEEP) // log 栈深度，默认为 1
                .setStackOffset(Constant.LogCat.STACK_OFFSET) // 设置栈偏移，比如二次封装的话就需要设置，默认为 0
                .setSaveDays(Constant.LogCat.SAVE_DATYS) // 设置日志可保留天数，默认为 -1 表示无限时长
                // 新增 ArrayList 格式化器，默认已支持 Array, Throwable, Bundle, Intent 的格式化输出
                .addFormatter(new L.IFormatter<ArrayList>() {
                    @Override
                    public String format(ArrayList list) {
                        return "ALog Formatter ArrayList { " + list.toString() + " }";
                    }
                });
        L.i(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> APP启动");
    }

    /**
     * 打开串口1
     */
    private void openSerialPort1() {
        L.i("打开串口");
        SerialPortTtys1CallBack.setCallBack(Ttys1Utils.getInstance());
        Ttys1Utils.getInstance().OpenPort();
        QrCodeUtils.initListener();
    }

    /**
     * 打开串口3
     */
    private void openSerialPort3() {
        L.i("打开串口");
        SerialPortTtys3CallBack.setCallBack(Ttys3Utils.getInstance());
        Ttys3Utils.getInstance().openPort();

    }

    /**
     * 初始化异常捕捉
     */
    private void initCrashException() {
        CrashException.init(AppApplication.getAppContext(), new CrashException.OnCrashExceptionListener() {
            @Override
            public void onCrashException(CrashModel crashModel) {
                L.e("异常", crashModel.toString());

                Intent intent = new Intent(getApplicationContext(), SystemStart_Aty.class);
                @SuppressLint("WrongConstant") PendingIntent restartIntent = PendingIntent.getActivity(
                        getApplicationContext(), 0, intent,
                        Intent.FLAG_ACTIVITY_NEW_TASK);
                AlarmManager mgr = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
                mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 3000,
                        restartIntent);
                android.os.Process.killProcess(android.os.Process.myPid());

            }
        });
    }


    public void setBuglyConfig() {
        // 获取当前包名
        String packageName = getPackageName();
// 获取当前进程名
        String processName = getProcessName(android.os.Process.myPid());
// 设置是否为上报进程
        CrashReport.UserStrategy strategy = new CrashReport.UserStrategy(getApplicationContext());
        strategy.setUploadProcess(processName == null || processName.equals(packageName));
//        CrashReport.setIsDevelopmentDevice(this, BuildConfig.DEBUG);
        strategy.setAppReportDelay(10000);                          //Bugly会在启动20s后联网同步数据
// 初始化Bugly
        CrashReport.initCrashReport(getApplicationContext(), "aacf3b1ffb", BuildConfig.DEBUG, strategy);
        CrashReport.setUserId(getApplicationContext(), DeviceUtils.getDeviceSn());
    }

    @Override
    public void onTrimMemory(int level) {
        super.onTrimMemory(level);
        L.i(String.format("%s onTrimMemory level: %s", getClass().getSimpleName(), level));
        GlideImageLoader.trimMemory(level);
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        L.i(String.format("%s onLowMemory", getClass().getSimpleName()));
        GlideImageLoader.lowMemory();
    }

    /**
     * 获取进程号对应的进程名
     *
     * @param pid 进程号
     * @return 进程名
     */
    private static String getProcessName(int pid) {
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader("/proc/" + pid + "/cmdline"));
            String processName = reader.readLine();
            if (!TextUtils.isEmpty(processName)) {
                processName = processName.trim();
            }
            return processName;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException exception) {
                exception.printStackTrace();
            }
        }
        return null;
    }
}
